home *** CD-ROM | disk | FTP | other *** search
- /* RawDisk-Handler V1.1
- © 1993 Christian Stieber
- stieber@informatik.tu-muenchen.de
- freely distributable */
-
- #ifndef EXEC_ALERTS_H
- #include <exec/alerts.h>
- #endif
-
- #ifndef DOS_FILEHANDLER_H
- #include <dos/filehandler.h>
- #endif
-
- #ifndef DEVICES_TRACKDISK_H
- #include <devices/trackdisk.h>
- #endif
-
- #include <string.h>
-
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- /***********************************************/
-
- struct MyFileHandle
- {
- long FilePos;
- };
-
- static char Version[]="$VER: RawDisk-Handler 1.1 (13.01.94) © Christian Stieber (stieber@informatik.tu-muenchen.de); freely distributable";
-
- /***********************************************/
-
- long MyDoIO(struct IOExtTD *IORequest)
-
- {
- long Error;
-
- Error=DoIO(IORequest);
- switch(Error)
- {
- case TDERR_WriteProt: return ERROR_DISK_WRITE_PROTECTED;
- case TDERR_DiskChanged: return ERROR_NO_DISK;
- case TDERR_NoMem: return ERROR_NO_FREE_STORE;
- case 0: return 0;
- default: return ABORT_DISK_ERROR;
- }
- }
-
- /***********************************************/
-
- void __saveds RawDisk(void)
-
- {
- struct DosLibrary *DOSBase;
- struct DosPacket *Packet;
- struct DeviceNode *DeviceNode;
- ULONG OpenCnt;
- int Quit;
- struct IOExtTD IORequest;
- struct DriveGeometry DriveGeometry;
- UBYTE *Buffer;
-
- if (!(DOSBase=(struct DosLibrary *)OpenLibrary("dos.library",37L)))
- {
- Alert(AT_DeadEnd | AG_OpenLib | AO_DOSLib);
- }
- IORequest.iotd_Req.io_Message.mn_ReplyPort=&((struct Process *)FindTask(NULL))->pr_MsgPort;
-
- Packet=WaitPkt();
- DeviceNode=BADDR(Packet->dp_Arg3);
-
- DeviceNode->dn_Task=IORequest.iotd_Req.io_Message.mn_ReplyPort;
-
- {
- struct FileSysStartupMsg *FileSysStartupMsg;
- struct DosEnvec *DosEnvec;
-
- FileSysStartupMsg=BADDR(DeviceNode->dn_Startup);
- DosEnvec=BADDR(FileSysStartupMsg->fssm_Environ);
- DriveGeometry.dg_TotalSectors=DosEnvec->de_BlocksPerTrack*DosEnvec->de_Surfaces*(DosEnvec->de_HighCyl-DosEnvec->de_LowCyl+1);
- DriveGeometry.dg_SectorSize=DosEnvec->de_SizeBlock*4;
- if (OpenDevice(((char *)BADDR(FileSysStartupMsg->fssm_Device))+1,FileSysStartupMsg->fssm_Unit,&IORequest,FileSysStartupMsg->fssm_Flags))
- {
- ReplyPkt(Packet,DOSFALSE,ERROR_OBJECT_NOT_FOUND);
- Quit=TRUE;
- }
- else
- {
- ReplyPkt(Packet,DOSTRUE,0);
- Quit=FALSE;
- }
- }
-
- OpenCnt=0;
- while (!Quit)
- {
- Packet=WaitPkt();
- switch(Packet->dp_Type)
- {
- case ACTION_FINDUPDATE:
- case ACTION_FINDINPUT:
- case ACTION_FINDOUTPUT: {
- struct FileHandle *FileHandle;
- struct MyFileHandle *MyFileHandle;
-
- if (!OpenCnt)
- {
- long Error;
- IORequest.iotd_Req.io_Command=TD_GETGEOMETRY;
- IORequest.iotd_Req.io_Data=&DriveGeometry;
- IORequest.iotd_Req.io_Length=sizeof(struct DriveGeometry);
- if (Error=MyDoIO(&IORequest))
- {
- ReplyPkt(Packet,DOSFALSE,Error);
- }
- if (!(Buffer=AllocMem(DriveGeometry.dg_SectorSize,0))) goto OutOfMem;
- }
-
- if (MyFileHandle=AllocMem(sizeof(struct MyFileHandle),0))
- {
- FileHandle=BADDR(Packet->dp_Arg1);
- MyFileHandle->FilePos=0;
- FileHandle->fh_Arg1=(long)MyFileHandle;
- OpenCnt++;
- ReplyPkt(Packet,DOSTRUE,0);
- }
- else
- {
- OutOfMem: ReplyPkt(Packet,DOSFALSE,ERROR_NO_FREE_STORE);
- }
- }
- break;
-
- case ACTION_READ: {
- struct MyFileHandle *MyFileHandle;
- long Length;
- UBYTE *Destination;
- long Error;
-
- MyFileHandle=(struct MyFileHandle *)Packet->dp_Arg1;
- Destination=(UBYTE *)Packet->dp_Arg2;
- Length=Packet->dp_Arg3;
- Error=0;
-
- while (!Error && Length && (MyFileHandle->FilePos!=DriveGeometry.dg_TotalSectors*DriveGeometry.dg_SectorSize))
- {
- int Size;
- int BufferPos;
- BufferPos=MyFileHandle->FilePos % DriveGeometry.dg_SectorSize;
- IORequest.iotd_Req.io_Command=CMD_READ;
- IORequest.iotd_Req.io_Data=Buffer;
- IORequest.iotd_Req.io_Length=DriveGeometry.dg_SectorSize;
- IORequest.iotd_Req.io_Offset=MyFileHandle->FilePos-BufferPos;
- if (!(Error=MyDoIO(&IORequest)))
- {
- Size=DriveGeometry.dg_SectorSize-BufferPos;
- if (Length<Size) Size=Length;
- memcpy(Destination,Buffer+BufferPos,Size);
- Length-=Size;
- Destination+=Size;
- MyFileHandle->FilePos+=Size;
- }
- }
- ReplyPkt(Packet,Error ? -1 : Packet->dp_Arg3-Length,Error);
- }
- break;
-
- case ACTION_WRITE: {
- struct MyFileHandle *MyFileHandle;
- long Length;
- UBYTE *Source;
- long Error;
-
- MyFileHandle=(struct MyFileHandle *)Packet->dp_Arg1;
- Source=(UBYTE *)Packet->dp_Arg2;
- Length=Packet->dp_Arg3;
- Error=0;
-
- while (Length)
- {
- if (MyFileHandle->FilePos!=DriveGeometry.dg_TotalSectors*DriveGeometry.dg_SectorSize)
- {
- int Size;
- int BufferPos;
- BufferPos=MyFileHandle->FilePos % DriveGeometry.dg_SectorSize;
- if (BufferPos || Length<DriveGeometry.dg_SectorSize)
- {
- IORequest.iotd_Req.io_Command=CMD_READ;
- IORequest.iotd_Req.io_Data=Buffer;
- IORequest.iotd_Req.io_Length=DriveGeometry.dg_SectorSize;
- IORequest.iotd_Req.io_Offset=MyFileHandle->FilePos-BufferPos;
- if (Error=MyDoIO(&IORequest))
- {
- break;
- }
- }
- Size=DriveGeometry.dg_SectorSize-BufferPos;
- if (Length<Size) Size=Length;
- memcpy(Buffer+BufferPos,Source,Size);
- IORequest.iotd_Req.io_Command=CMD_WRITE;
- IORequest.iotd_Req.io_Data=Buffer;
- IORequest.iotd_Req.io_Length=DriveGeometry.dg_SectorSize;
- IORequest.iotd_Req.io_Offset=MyFileHandle->FilePos-BufferPos;
- if (Error=MyDoIO(&IORequest))
- {
- break;
- }
- Length-=Size;
- Source+=Size;
- MyFileHandle->FilePos+=Size;
- }
- else
- {
- if (!(Packet->dp_Arg3-Length))
- {
- Error=ERROR_DISK_FULL;
- }
- break;
- }
- }
- ReplyPkt(Packet,Error ? -1 : Packet->dp_Arg3-Length,Error);
- }
- break;
-
- case ACTION_SEEK: {
- struct MyFileHandle *MyFileHandle;
- long NewFilePos;
-
- NewFilePos=-1;
- MyFileHandle=(struct MyFileHandle *)Packet->dp_Arg1;
- switch(Packet->dp_Arg3)
- {
- case OFFSET_BEGINNING: NewFilePos=Packet->dp_Arg2;
- break;
- case OFFSET_CURRENT: NewFilePos=MyFileHandle->FilePos+Packet->dp_Arg2;
- break;
- case OFFSET_END: NewFilePos=DriveGeometry.dg_TotalSectors*DriveGeometry.dg_SectorSize-Packet->dp_Arg2;
- break;
- }
- if (NewFilePos<0 || NewFilePos>DriveGeometry.dg_TotalSectors*DriveGeometry.dg_SectorSize)
- {
- ReplyPkt(Packet,-1,ERROR_SEEK_ERROR);
- }
- else
- {
- long OldPos=MyFileHandle->FilePos;
- MyFileHandle->FilePos=NewFilePos;
- ReplyPkt(Packet,OldPos,0);
- }
- }
- break;
-
- case ACTION_END: {
- long Error;
-
- Error=0;
- FreeMem((struct MyFileHandle *)Packet->dp_Arg1,sizeof(struct MyFileHandle));
- if (!--OpenCnt)
- {
- IORequest.iotd_Req.io_Command=CMD_UPDATE;
- Error=MyDoIO(&IORequest);
- IORequest.iotd_Req.io_Command=TD_MOTOR;
- IORequest.iotd_Req.io_Length=0;
- DoIO(&IORequest);
- FreeMem(Buffer,DriveGeometry.dg_SectorSize);
- }
- ReplyPkt(Packet,Error ? DOSTRUE : DOSFALSE,Error);
- }
- break;
-
- case ACTION_DIE: if (!OpenCnt)
- {
- Forbid();
- ReplyPkt(Packet,DOSTRUE,0);
- while (!IsMsgPortEmpty(IORequest.iotd_Req.io_Message.mn_ReplyPort))
- {
- ReplyPkt(WaitPkt(),DOSFALSE,ERROR_OBJECT_NOT_FOUND);
- }
- Quit=TRUE;
- }
- else
- {
- ReplyPkt(Packet,DOSFALSE,ERROR_OBJECT_IN_USE);
- }
- break;
-
- default: {
- ReplyPkt(Packet,DOSFALSE,ERROR_ACTION_NOT_KNOWN);
- }
- break;
- }
- }
-
- {
- BPTR SegList;
- SegList=DeviceNode->dn_SegList;
- DeviceNode->dn_Task=NULL;
- DeviceNode->dn_SegList=NULL;
- CloseDevice(&IORequest);
- UnLoadSeg(DeviceNode->dn_SegList);
- CloseLibrary((struct Library *)DOSBase);
- }
- }
-